module core_top(
    input           aclk,
    input           aresetn,
    input    [ 7:0] intrpt, 
    //AXI interface 
    //read reqest
    output   [ 3:0] arid,
    output   [31:0] araddr,
    output   [ 7:0] arlen,
    output   [ 2:0] arsize,
    output   [ 1:0] arburst,
    output   [ 1:0] arlock,
    output   [ 3:0] arcache,
    output   [ 2:0] arprot,
    output          arvalid,
    input           arready,
    //read back
    input    [ 3:0] rid,
    input    [31:0] rdata,
    input    [ 1:0] rresp,
    input           rlast,
    input           rvalid,
    output          rready,
    //write request
    output   [ 3:0] awid,
    output   [31:0] awaddr,
    output   [ 7:0] awlen,
    output   [ 2:0] awsize,
    output   [ 1:0] awburst,
    output   [ 1:0] awlock,
    output   [ 3:0] awcache,
    output   [ 2:0] awprot,
    output          awvalid,
    input           awready,
    //write data
    output   [ 3:0] wid,
    output   [31:0] wdata,
    output   [ 3:0] wstrb,
    output          wlast,
    output          wvalid,
    input           wready,
    //write back
    input    [ 3:0] bid,
    input    [ 1:0] bresp,
    input           bvalid,
    output          bready,

    //debug
    input           break_point,//无需实现功能，仅提供接口即可，输入1’b0
    input           infor_flag,//无需实现功能，仅提供接口即可，输入1’b0
    input  [ 4:0]   reg_num,//无需实现功能，仅提供接口即可，输入5’b0
    output          ws_valid,//无需实现功能，仅提供接口即可
    output [31:0]   rf_rdata,//无需实现功能，仅提供接口即可

    //debug info
    output [31:0] debug0_wb_pc,
    output [ 3:0] debug0_wb_rf_wen,
    output [ 4:0] debug0_wb_rf_wnum,
    output [31:0] debug0_wb_rf_wdata
);
//cpu inst 
wire inst_rd_req;
wire [2:0]inst_rd_type;
wire [31:0]inst_rd_addr;
wire inst_rd_rdy;
wire inst_ret_valid;
wire inst_ret_last;
wire [31:0]inst_ret_data;
//cpu data
wire        data_rd_req;
wire [2:0]  data_rd_type;
wire [31:0] data_rd_addr;
wire        data_rd_rdy;
wire        data_ret_valid;
wire        data_ret_last;
wire [31:0] data_ret_data;

wire        data_wr_req;//写请求
wire [2:0]  data_wr_type;
wire [3:0]  data_wr_wstrb;
wire [31:0] data_wr_addr;//写首地址
wire [127:0]data_wr_data;
wire data_wr_rdy;
cpu_top cpu_top0(
    .clk              (aclk   ),
    .resetn           (aresetn),  //low active

    //inst
    .inst_rd_req(inst_rd_req),
    .inst_rd_type(inst_rd_type),
    .inst_rd_addr(inst_rd_addr),
    .inst_rd_rdy(inst_rd_rdy),
    .inst_ret_valid(inst_ret_valid),
    .inst_ret_last(inst_ret_last),
    .inst_ret_data(inst_ret_data),
    //指令cache不用写回
    .inst_wr_req(),//写请求
    .inst_wr_type(),
    .inst_wr_addr(),//写首地址
    .inst_wr_wstrb(),
    .inst_wr_data(),
    .inst_wr_rdy(1),
    
    //data
    .data_rd_req(data_rd_req),
    .data_rd_type(data_rd_type),
    .data_rd_addr(data_rd_addr),
    .data_rd_rdy(data_rd_rdy),
    .data_ret_valid(data_ret_valid),
    .data_ret_last(data_ret_last),
    .data_ret_data(data_ret_data),

    .data_wr_req(data_wr_req),//写请求
    .data_wr_type(data_wr_type),
    .data_wr_addr(data_wr_addr),//写首地址
    .data_wr_wstrb(data_wr_wstrb),
    .data_wr_data(data_wr_data),
    .data_wr_rdy(data_wr_rdy),

    //debug interface
    .debug_wb_pc      (debug0_wb_pc      ),
    .debug_wb_rf_we   (debug0_wb_rf_wen   ),
    .debug_wb_rf_wnum (debug0_wb_rf_wnum ),
    .debug_wb_rf_wdata(debug0_wb_rf_wdata)
);
reg [2:0] status=0;
//

//cpu_inst
//ar
wire [3 :0] arid1   =0;
wire [31:0] araddr1 =inst_rd_addr;
wire [2 :0] arsize1 =2;
wire        arvalid1=inst_rd_req;
//r

//cpu_data 
//ar
wire [3 :0] arid2   =1;
wire [31:0] araddr2 =data_rd_addr;
wire [2 :0] arsize2 =2;
wire        arvalid2=data_rd_req;
wire [7 :0]arlen2=(data_rd_type==3'b100)?3:0;
//r

//写buffer
reg is_empty=1;
reg [3:0]w_count=0;
reg [127:0]buffer_data=0;
reg [31:0]buffer_addr=0;
reg [2:0]w_type=0;
reg [3:0]w_wstrb=0;

//整体
//ar
assign arid=(status==1)?0:
            (status==2)?1:0;
assign araddr=(status==1)?araddr1:
            (status==2)?araddr2:0;
assign arlen  =status==2?arlen2:3;
assign arsize=(status==1)?arsize1:
            (status==2)?arsize2:0;
assign arburst=2'b01;
assign arlock =0;
assign arcache=0;
assign arprot =0;
assign arvalid=(status==1)?arvalid1:
            (status==2)?arvalid2:0;
//r
assign rready =(status==3)|(status==4);

//aw
assign awid   =1;
assign awaddr =buffer_addr ;
assign awlen  =(w_type==3'b100)?3:0;
assign awsize =2 ;
assign awburst=2'b01;
assign awlock =0;
assign awcache=0;
assign awprot =0;
assign awvalid=(status==7);
//w
assign wid=1;
assign wdata=w_count==0?buffer_data[31:0]:
             w_count==1?buffer_data[63:32]:
             w_count==2?buffer_data[95:64]:
             w_count==3?buffer_data[127:96]:0;
assign wstrb=w_wstrb;
assign wlast=(w_type==3'b100)?(w_count==3):1;
assign wvalid =(status==6);
//b
assign bready=(status==5);

//写缓冲

always @(posedge aclk) begin
    if(data_wr_req&is_empty)begin
        buffer_data<=data_wr_data;
        buffer_addr<=data_wr_addr;
        w_type<=data_wr_type;
        w_wstrb<=data_wr_wstrb;
        is_empty<=0;
    end
    if(status==5&bvalid)is_empty<=1;
end

always @(posedge aclk) begin
    if(~aresetn)begin
        status<=0;
    end else
    case(status)
        0:begin
            w_count<=0;
            if(~is_empty)status <=7;
            else if(data_rd_req)status <= 2;
            else if(inst_rd_req)status <= 1;
            else status <= 0;
        end
        1:begin
            if(arready)status <= 3;
        end
        2:begin
            if(arready)status <= 4;
        end
        3:begin
            if(rvalid&rlast)status <= 0;
        end
        4:begin
            if(rvalid&rlast)status<=0;
        end
        5:begin
            if(bvalid)begin
                status <= 0;
            end
        end
        6:begin
            if(wready&wlast)status<=5;
            else if(wready)w_count<=w_count+1;
        end
        7:begin
            if(awready)status<=6;
        end
    endcase
end
assign inst_rd_rdy=(status==1)&(arready);
assign inst_ret_valid=(status==3)&rvalid;
assign inst_ret_last=(status==3)&rlast;
assign inst_ret_data=rdata;



assign data_rd_rdy=status==2&arready;
assign data_ret_valid=status==4&rvalid;
assign data_ret_last=status==4&rlast;
assign data_ret_data=rdata;

assign data_wr_rdy=is_empty;

//
wire ddd=buffer_addr==araddr&~is_empty&status!=0;

endmodule